package com.dogsong.liteflow.editor.component;

import com.dogsong.liteflow.editor.constant.ContextConstant;
import com.dogsong.liteflow.editor.slot.DataContext;
import com.yomahub.liteflow.core.NodeBooleanComponent;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Component("arrayBooleanCmp")
public class ArrayBooleanCmp extends NodeBooleanComponent {
    @Override
    public boolean processBoolean() throws Exception {
        DataContext dataContext = this.getContextBean(DataContext.class);
        Object obj1 = dataContext.getDataMap().get(this.getBindData(ContextConstant.INPUT_1_DATA,
                String.class));
        Object obj2 = dataContext.getDataMap().get(this.getBindData(ContextConstant.INPUT_2_DATA,
                String.class));

        // 添加类型检查以确保安全转换
        if (!(obj1 instanceof Collection) && !(obj1 != null && obj1.getClass().isArray()) ||
                !(obj2 instanceof Collection) && !(obj2 != null && obj2.getClass().isArray())) {
            throw new IllegalArgumentException("输入数据必须是数组或集合类型");
        }

        String compare = ((Map<String,String>) this.getRequestData()).get(this.getTag());

        switch (compare) {
            case "length>":
                return getArrayLength(obj1) > getArrayLength(obj2);
            case "length<":
                return getArrayLength(obj1) < getArrayLength(obj2);
            case "length>=":
                return getArrayLength(obj1) >= getArrayLength(obj2);
            case "length<=":
                return getArrayLength(obj1) <= getArrayLength(obj2);
            case "length==":
                return getArrayLength(obj1) == getArrayLength(obj2);
            case "contains":
                return containsAll(obj1, obj2);
            case "notContains":
                return !containsAll(obj1, obj2);
            case "isEmpty":
                return isEmpty(obj1);
            case "isNotEmpty":
                return !isEmpty(obj1);
            default:
                throw new IllegalArgumentException("不支持的数组比较操作: " + compare);
        }
    }

    private int getArrayLength(Object array) {
        if (array == null) {
            return 0;
        }
        if (array instanceof Object[]) {
            return ((Object[]) array).length;
        }
        if (array instanceof Collection) {
            return ((Collection<?>) array).size();
        }
        if (array.getClass().isArray()) {
            return Array.getLength(array);
        }
        // 如果不是数组类型，视为长度为1
        return 1;
    }

    private boolean isEmpty(Object array) {
        return getArrayLength(array) == 0;
    }

    private boolean containsAll(Object array1, Object array2) {
        if (array1 == null || array2 == null) {
            return false;
        }

        // 获取array2中的所有元素
        Object[] elements2;
        if (array2 instanceof Object[]) {
            elements2 = (Object[]) array2;
        } else if (array2 instanceof Collection) {
            elements2 = ((Collection<?>) array2).toArray();
        } else if (array2.getClass().isArray()) {
            int length = Array.getLength(array2);
            elements2 = new Object[length];
            for (int i = 0; i < length; i++) {
                elements2[i] = Array.get(array2, i);
            }
        } else {
            elements2 = new Object[]{array2};
        }

        // 检查array1是否包含array2的所有元素
        for (Object element : elements2) {
            if (!contains(array1, element)) {
                return false;
            }
        }
        return true;
    }

    private boolean contains(Object array, Object element) {
        if (array == null) {
            return false;
        }
        if (array instanceof Object[]) {
            return ArrayUtils.contains((Object[]) array, element);
        }
        if (array instanceof Collection) {
            return ((Collection<?>) array).contains(element);
        }
        if (array.getClass().isArray()) {
            int length = Array.getLength(array);
            for (int i = 0; i < length; i++) {
                if (element != null && element.equals(Array.get(array, i))) {
                    return true;
                }
            }
            return false;
        }
        return array.equals(element);
    }

    private int getCompareValue(Object value) {
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.parseInt(value.toString());
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("数组长度比较时，比较值必须是整数: " + value);
        }
    }
}
